package editor;

import game.Livello;

import java.awt.Color;
import java.awt.Image;
import java.awt.Toolkit;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;

import suono.Sound;

public class Editor {
	private int width;
	private int height;
	private String [] imagesMattoni;
	private String [] imagesBonus;
	private String [] imagesNemici;
	private String [] imagesSfondi;
	private String [] sounds;
	private String [] levels;
	private Sound suoni;
	private String soundTrack;
	private char mappaLivello [][];
	private Color sfondoEditor;
	private String fileSfondo;
	private Image immagineSfondo;
	private char simbolo;
	private char drawItemType;
	private boolean salvato;
	private boolean exit;
	private boolean modificato;
	private String nome;
	private String currentTileSet;
	private Image drawItem;
	private ArrayList<SpriteImage> images;
	private ArrayList<String> imagesTiles;
	private HashMap<String,String[]> tilePath;
	private Toolkit tool;
	
	/**
	 * Crea un nuovo oggetto di tipo Editor.
	 * @param width altezza livello creato da un oggetto di tipo Editor.
	 * @param height lunghezza livello creato di un oggetto di tipo Editor.
	 */
	public Editor(int width, int height){
		images = new ArrayList<SpriteImage>();
		this.nome = null;
		this.immagineSfondo = null;
		this.fileSfondo = null;
		this.soundTrack = null;
		this.width = width;
		this.height = height;
		this.suoni = new Sound();
		this.sfondoEditor = Color.WHITE;
		this.drawItem = null;
		this.soundTrack = null;
		this.salvato = false;
		this.exit = false;
		this.modificato = false;
		this.tool = Toolkit.getDefaultToolkit();
		this.tilePath = new HashMap<String,String[]>();
		this.imagesTiles  = new ArrayList<String>(0);
		inizializzaVettoriElementi();
		inizializzaMappaLivello();
	}
	
	/**
	 * Iniziallizza i vettori che contengono i percorsi
	 * degli elementi grafici e sonori utilizzabili 
	 * nell'editor.
	 */
	public void inizializzaVettoriElementi(){
		String percorsoTile = "editor"+File.separator+"tile";
		String percorsoBonus = "editor"+File.separator+"bonus";
		String percorsoSounds = "editor"+File.separator+"suoni";
		String percorsoNemici = "editor"+File.separator+"enemies";
		String percorsoLivelli = "editor"+File.separator+"levels";
		String percorsoSfondi = "editor"+File.separator+"sfondi";
		File fileTile = new File (percorsoTile);
		File fileBonus = new File (percorsoBonus);
		File fileSounds = new File (percorsoSounds);
		File fileNemici = new File (percorsoNemici);
		File fileLivelli = new File (percorsoLivelli);
		File fileSfondi = new File (percorsoSfondi);
		imagesMattoni = fileTile.list();
		imagesBonus = fileBonus.list();
		imagesNemici = fileNemici.list();
		imagesSfondi = fileSfondi.list();
		levels = fileLivelli.list();
		sounds = fileSounds.list();
		String tileSet;
		
		for (int k=0; k < imagesBonus.length; k++){
			imagesBonus[k]= percorsoBonus + "/" + imagesBonus[k];
		}
		for (int k=0; k < imagesSfondi.length; k++){
			imagesSfondi[k]= percorsoSfondi + "/" + imagesSfondi[k];
		}
		for (int k=0; k < imagesMattoni.length; k++){
			tileSet = imagesMattoni[k];
			imagesTiles.add(percorsoTile + "/" + imagesMattoni[k]);
			File f = new File(imagesTiles.get(k));
			String s[] = f.list();
			for(int i=0; i<s.length; i++){
				s[i]= imagesTiles.get(k)+"/"+s[i];
			}
			tilePath.put(tileSet, s);
		}
		for (int k=0; k < imagesNemici.length; k++){
			imagesNemici[k]= percorsoNemici + "/" + imagesNemici[k];
		}
		for (int k=0; k < sounds.length; k++){
			suoni.addSuoni(".."+File.separator+percorsoSounds+File.separator+sounds[k]);
		}
		
	}
	
	private void inizializzaMappaLivello(){
		this.mappaLivello = new char [this.height][this.width];
		for (int i=0; i < this.height; i++){
			for (int j=0; j < this.width; j++){
				mappaLivello[i][j] = ' ';
			}
		}
	}
	
	/**
	 * Inserisce il simbolo alla posizione [riga][colonna] della matrice
	 * di caratteri che rappresenta la mappa del livello.  
	 * @param simbolo simbolo da inserire
	 * @param riga una riga della matrice
	 * @param colonna una colonna della matrice
	 */
	public void aggiornaMatrice(char simbolo, int riga, int colonna ){
		mappaLivello[riga][colonna] = simbolo;
	}
	
	/**
	 * Salva su file di testo la mappa di caratteri e tutte le informazioni
	 * necessarie per visualizzare correttamente il livello creato.
	 */
	public void salvaLivello(){
		String dimension = "%" + String.valueOf(width) + "%" + String.valueOf(height);
		String background = "color:"+String.valueOf(sfondoEditor.getRGB());
		String tileset = "tileset:" + this.currentTileSet;
		String imgBackground = "background:" + this.fileSfondo;
		String sottofondo = "sound:" + this.soundTrack;
		try {
			FileWriter file = new FileWriter("editor"+ File.separator+"levels"+ File.separator+ this.nome + ".rgl");
			BufferedWriter buff = new BufferedWriter(file);
			buff.write(dimension);
			buff.newLine();
			buff.write(tileset);
			buff.newLine();
			for (int i=0; i < this.height; i++){
				buff.write(mappaLivello[i]);
				buff.newLine();
			}
			if(this.fileSfondo != null){
				buff.write(imgBackground);
				buff.newLine();
			}
			if(this.soundTrack != null){
				buff.write(sottofondo);
				buff.newLine();
			}
			buff.write(background);
			buff.flush();
			file.close();
			this.salvato = true;
			this.modificato = false;
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * Legge la lunghezza del livello dal file di testo corrispondente.
	 * @param nomeFile nome del file
	 * @return	restitusce la lunghezza del livello.
	 */
	public int leggiDimensioni(String nomeFile){
		int lungh =0;
		try{
			FileReader read = new FileReader("editor"+File.separator+"levels"+File.separator+nomeFile);
			BufferedReader in = new BufferedReader (read);
			String linea = in.readLine();
			if (linea.startsWith("%")){
				String[] s = linea.split("%");
				lungh = Integer.valueOf(s[1]).intValue();
			}
			//else...inserire eccezione tipo "File non valido".
			in.close();
		}
		catch (FileNotFoundException e){System.out.println(e);}
		catch (IOException e){System.out.println(e);}
		return lungh;
	}
	
	/**
	 * Apre un livello precedentemente creato.
	 * @param nomeFile nome del file
	 */
	public void apriLivello(String nomeFile){
		try{
			String temp[]=nomeFile.split(".rgl");
			System.out.println(temp[0]);
			this.nome = temp[0];
			FileReader read = new FileReader("editor"+File.separator+"levels"+File.separator+nomeFile);
			BufferedReader in = new BufferedReader (read);
			String linea;
			int k=0;
			while ( (linea=in.readLine())!= null){
				if (!linea.startsWith("#") && !linea.startsWith("%")){
					if(linea.startsWith("color:")){
						String[] s = linea.split("color:");
						this.sfondoEditor = new Color(Integer.valueOf(s[1]).intValue());
					} 
					else if(linea.startsWith("tileset:")){
						String[] s = linea.split("tileset:");
						this.currentTileSet =s[1];
					}
					else if (linea.startsWith("background:")) {
						String[] s2 = linea.split("background:");
						this.fileSfondo= s2[1];
						this.immagineSfondo = tool.getImage("images/sfondi/"+s2[1]);				
					}
					else if (linea.startsWith("sound:")) {
						String[] s2 = linea.split("sound:");
						this.soundTrack = s2[1];				
					}
					else{
						String [] str1 = linea.split("");
						for (int j=1; j < str1.length; j++){
							aggiornaMatrice(str1[j].charAt(0), k, j-1);
							aggiungiImmagine(str1[j],(j-1)*Livello.TILE_SIZE, k*Livello.TILE_SIZE);
						}
						k++;
					}
				}
			}
			in.close();
			salvato = true;
		}
		catch (FileNotFoundException e){System.out.println(e);}
		catch (IOException e){System.out.println(e);}
	}
	
	private void aggiungiImmagine(String s,int coordx, int coordy){
		switch(s.charAt(0)) {
		 case 'A':
			 this.images.add(new SpriteImage(tool.getImage("editor/tile/"+currentTileSet+"/"+"tile_A.png"),coordx,coordy,'T')); 
			 break;
		 case 'B':
			 this.images.add(new SpriteImage(tool.getImage("editor/tile/"+currentTileSet+"/"+"tile_B.png"),coordx,coordy,'T'));
			 break;
		 case 'C':
			 this.images.add(new SpriteImage(tool.getImage("editor/tile/"+currentTileSet+"/"+"tile_C.png"),coordx,coordy,'T'));
			 break;
		 case 'D':
			 this.images.add(new SpriteImage(tool.getImage("editor/tile/"+currentTileSet+"/"+"tile_D.png"),coordx,coordy,'T'));
			 break;
		 case 'E':
			 this.images.add(new SpriteImage(tool.getImage("editor/tile/"+currentTileSet+"/"+"tile_E.png"),coordx,coordy,'T')); 
			 break;
		 case 'F':
			 this.images.add(new SpriteImage(tool.getImage("editor/tile/"+currentTileSet+"/"+"tile_F.png"),coordx,coordy,'T'));
			 break;
		 case 'G':
			 this.images.add(new SpriteImage(tool.getImage("editor/tile/"+currentTileSet+"/"+"tile_G.png"),coordx,coordy,'T'));
			 break;
		 case 'H':
			 this.images.add(new SpriteImage(tool.getImage("editor/tile/"+currentTileSet+"/"+"tile_H.png"),coordx,coordy,'T'));
			 break;
		 case '!':
			 this.images.add(new SpriteImage(tool.getImage("editor/bonus/energy_!.gif"),coordx,coordy,'B'));
			 break;
		 case '@':
			 this.images.add(new SpriteImage(tool.getImage("editor/bonus/stellaBlu_@.gif"),coordx,coordy,'B'));
			 break;
		 case '$':
			 this.images.add(new SpriteImage(tool.getImage("editor/bonus/cuoreRotante_$.gif"),coordx,coordy,'B'));
			 break;
		 case '&':
			 this.images.add(new SpriteImage(tool.getImage("editor/bonus/porta_&.gif"),coordx,coordy,'B'));
			 break;
		 case '1':
			 this.images.add(new SpriteImage(tool.getImage("editor/enemies/nemico1_1.gif"),coordx,coordy,'N'));
			 break;
		 case '2':
			 this.images.add(new SpriteImage(tool.getImage("editor/enemies/nemico2_2.gif"),coordx,coordy,'N'));
			 break;
		}
	}
	
	public String[] getImagesMattoni() {
		return imagesMattoni;
	}

	public String[] getImagesBonus() {
		return imagesBonus;
	}
	
	public String[] getImagesNemici() {
		return imagesNemici;
	}
	
	public String[] getSounds() {
		return sounds;
	}
	
	public String[] getLevels() {
		return levels;
	}
	
	public String[] getImagesSfondi() {
		return imagesSfondi;
	}

	public int getWidth() {
		return width;
	}
	
	public void setWidth(int width) {
		this.width = width;
	}

	public int getHeight() {
		return height;
	}
	public Sound getSuoni(){
		return suoni;
	}
	public Color getSfondoEditor() {
		return sfondoEditor;
	}

	public void setSfondoEditor(Color sfondoEditor) {
		this.sfondoEditor = sfondoEditor;
	}

	public char getSimbolo() {
		return simbolo;
	}

	public void setSimbolo(char simbolo) {
		this.simbolo = simbolo;
	}

	public Image getDrawItem() {
		return drawItem;
	}

	public void setDrawItem(Image drawItem) {
		this.drawItem = drawItem;
	}

	public boolean isSalvato() {
		return salvato;
	}

	public void setSalvato(boolean salvato) {
		this.salvato = salvato;
	}

	public boolean isExit() {
		return exit;
	}

	public void setExit(boolean exit) {
		this.exit = exit;
	}

	public String getNome() {
		return nome;
	}

	public void setNome(String nome) {
		this.nome = nome;
	}

	public boolean isModificato() {
		return modificato;
	}

	public void setModificato(boolean modificato) {
		this.modificato = modificato;
	}

	public ArrayList<SpriteImage> getImages() {
		return images;
	}

	public void setImages(ArrayList<SpriteImage> images) {
		this.images = images;
	}

	public ArrayList<String> getImagesTiles() {
		return imagesTiles;
	}

	public HashMap<String, String[]> getTilePath() {
		return tilePath;
	}

	public char getDrawItemType() {
		return drawItemType;
	}

	public void setDrawItemType(char drawItemType) {
		this.drawItemType = drawItemType;
	}

	public String getCurrentTileSet() {
		return currentTileSet;
	}

	public void setCurrentTileSet(String currentTileSet) {
		this.currentTileSet = currentTileSet;
	}

	public Image getImmagineSfondo() {
		return immagineSfondo;
	}

	public void setFileSfondo(String fileSfondo) {
		this.fileSfondo = fileSfondo;
		if(fileSfondo != null)
			this.immagineSfondo = tool.getImage("images/sfondi/" + fileSfondo);
		else
			this.immagineSfondo = null;
	}

	public String getSoundTrack() {
		return soundTrack;
	}

	public void setSoundTrack(String soundTrack) {
		this.soundTrack = soundTrack;
	}


	

	
}
